/*
============================================================================
 Name			: BluetoothResponder.h
 Author	  		: 
Copyright (c) Symbian Ltd 2008. All rights reserved.
 Description 	: CBluetoothResponder has been implemented as a state machine that incapsulates all
				  the BT stack parts that are responsible for advertising the BT service using the SDP server,
				  setting BT security, listening for an incoming connection and transferring data to/from a connected
				  remote device (Master). CBluetoothResponder acts as the Slave part in a multiplayer game.

				  The CBluetoothResponder's state machine includes the following operations:
				  1) Finding an available RFCOMM's port
				  2) Binding the BT socket to the RFCOMM's port
				  3) Advertising the RPS server using the SDP server
				  4) Setting BT security
				  5) Listening for an incoming connection (Master connection)
				  6) Both sending/receiving data to/from the remote device (Master)
				  7) Callbacks to report to the App's engine the state machine error and completion of events such as listening
				     for connection, connection completed, report data, sending data completed.
				     
				  Note that if at any stage we receive an error then the state machine is reset to the EIdle
				  state and all resources previously allocated are closed.
============================================================================
*/

#ifndef __BLUETOOTHRESPONDER_H__
#define __BLUETOOTHRESPONDER_H__

// INCLUDES
#include <bt_sock.h>
#include <btmanclient.h>
#include <btsdp.h>
#include "BluetoothSocketWriterReader.h"
#include "CommonInterfaces.h"

// FORWARD DECLARATIONS
class CSocketReader;
class CSocketWriter;


class CBluetoothServiceAdvertiser;


// CLASS DECLARATION
/**
* CBluetoothResponder
* Advertises a BT service and listens for incoming connection
*/
class CBluetoothResponder : public CBluetoothConnectionBase, 
							public MBluetoothServiceAdvertiserObserver,
							public MSocketWriterReaderObserver
    {
public:
	/**
	* TResponderState
	* State Machine
	*/
	enum TResponderState 
	    {
	    EIdle,					//State Machine's entry point
	    EFindingAvailablePort,	//Finding an available RFCOMM's port
	    EBinding,				//Binding the listening socket to the BT device address and RFCOMM's port
	    EAdvertising,			//Advertising the service into SDP's database
	    ERegisteringService,	//Setting the BT security
	    EListening,				//Listening for incoming connection
	    EWaitingForData,		//Waiting for incoming data
	    ESendingData,			//Sending data to the remote BT device
	    };

public:
	/**
	* Two stage constructor
	* @param aRespObs		Interface to report to the caller the status of the connection and incoming/sending data completion 
	* @param aSocketServer	A handle to an existing session on the socket server (ESock)
	*/
    static CBluetoothResponder* NewL(MBluetoothObserver& aRespObs, RSocketServ& aSocketServer);

	/**
	* Destructor
	*/
    ~CBluetoothResponder();
	
	//From MBluetoothServiceAdvertiserObserver
	/**
	* Callback to notify any error during BT service advertising 
	* @param aError An error
	*/
	void ReportAdvertiserErr(TInt aError);
	
	/**
	* Callback to notify the completion of the service advertising
	*/
	void AdvertiserComplete();
	
	//From MSocketWriterReaderObserver
	/**
	* Callback to notify the caller of the sending data completion
	* @param aError	 KErrNone if succesful, otherwise one of the system errors
	*/
	void WriteComplete(TInt aError);
	
	/**
	* Callback to notify the caller of incoming data from the remote BT device
	* @param aData	 A descriptor for the data being received from the remote BT device
	* @param aError	 KErrNone if succesful, otherwise one of the system errors
	*/
	void ReportData(const TDesC8& aData, TInt aError);

	//From CBluetoothConnectionBase
	/**
	* Send the data to the remote BT device. On completion calls MBluetoothObserver::SendDataComplete
	* @param aData	A descriptor for the data being sent to the remote BT device
	*/
	void SendData(const TDesC8& aData);

	/**
	* Kicks off the state machine
	*/
	void StartL();
	
private:
	/**
	* Constructor
	* @param aRespObs		Interface to report to the caller the status of the connection, incoming/sending data completion 
	* @param aSocketServer	A handle to an existing session on the socket server (ESock)
	*/
    CBluetoothResponder(MBluetoothObserver& aRespObs, RSocketServ& aSocketServer);

	/**
	* Second phase constructor 
	*/
    void ConstructL();
    
	// From CActive
	/**
	* Handles CBluetoothResponder's state machine completion events
	*/
	virtual void RunL();
	
	/**
	* Cancels all outstanding BT socket operations
	*/
	virtual void DoCancel();
	
	/**
	* Handles a leave occurring in the request completion event handler RunL()
	* @param aError	 The leave code
	* @return TInt	 The default implementation returns aError.A derived class implementation should return KErrNone,
	*				 if it handles the leave; otherwise it should return any suitable value to cause the handling
	*				 of the error to be propagated back to the active scheduler.
	*/
	TInt RunError(TInt aError);
	
	/**
	* Call User::RequestComplete on this active object
	*/
	void SelfComplete();
	
	/**
	* Finds an available RFCOMM's port
	*/
	void FindAvailablePortL();
	
	/**
	* Binds the listening socket to the BT device address and the available RFCOMM's port
	*/
	void BindToPortL();
	
	/**
	* Sets the BT security
	*/
	void RegisterService();
	
	/**
	* Listens for incoming connection
	*/
	void ListenL();
	
	/**
	* Waits for incoming data
	*/
	void WaitForData();

private:
	/**
	* Interface to report to the caller the status of the connection, incoming/sending data completion 
	*/
	MBluetoothObserver& iRespObs;
	
	/**
	* A handle to an existing session on the socket server (ESock)
	*/
	RSocketServ& iSocketServer;
	
 	/**
	* State Machine
	*/
	TResponderState iState;
	
 	/**
	* RFCOMM's port
	*/
	TInt iPort;
	
 	/**
	* Client endpoint to the RFCOMM protocol
	*/
	RSocket iListeningSocket;
	
 	/**
	* Blank socket
	*/
	RSocket iAcceptingSocket;
	
 	/**
	* Bluetooth socket address
	*/
	TBTSockAddr iBtSocketAddr;
	
 	/**
	* Active object responsible for advertising the service
	*/
	CBluetoothServiceAdvertiser* iServiceAdvertiser;
	
	/**
	* Responsible for notifying the connector either when data arrives from the remote device
	* or when a connection error occurs
	*/
	CSocketReader* iBtSocketReader;
	
	/**
	* Responsible for sending data from the connetor to the remote device and notifing the connector when
	* the transfer is completed.
	*/
	CSocketWriter* iBtSocketWriter;
	
	/**
	* The security settings of a bluetooth service
	*/
	TBTServiceSecurity iBtSecurity;
   };

#endif // __BLUETOOTHRESPONDER_H__
